//手写或使用c++17提供的any
#include<iostream>
#include<assert.h>
#include<algorithm>
#include<unistd.h>
#include<typeinfo>
#include<any>
#include<string>
#include <boost/type_index.hpp>


#include<any>

class Any
{
private:
    class holder
    {
    public:
        virtual ~holder(){}
        virtual holder*clone()=0;//纯虚函数，抽象类，派生类必须重写函数
        // virtual const std::type_info& type() = 0;
        virtual boost::typeindex::type_index type()=0;
    };
    template<class T>
    class placeholder:public holder
    {
    public:
        placeholder(const T&val):_val(val){}
        // 获取子类对象保存的数据类型
        // virtual const std::type_info&type()
        // {
        //     return typeid(T);
        // }
        // 派生类 placeholder 中：
        virtual boost::typeindex::type_index type()
        {
        return boost::typeindex::type_id_with_cvr<T>();  // 正确返回 Boost 类型
        }
        // 针对当前的对象自身，克隆出一个新的子类对象
        virtual  holder*clone()
        {
            return new placeholder(_val);
        }
        ~placeholder()
        {
        }
    public:
        T _val;
    };
    holder* _content;//指向placehodler的指针
public:
    Any():_content(nullptr){}
    template<class T>
    Any(const T& val):_content(new placeholder<T>(val)){}                                             
    Any(const Any&other):_content(other._content ? other._content->clone(): nullptr) {}
    ~Any(){delete _content;}
    //构造函数：负责 “从无到有” 创建对象，只需初始化新资源，无旧资源可释放。
    // 赋值运算符：负责 “已有对象的更新”，必须处理旧资源的释放（否则会内存泄漏）
    Any& swap(Any& other)
    {
        std::swap(_content,other._content);
        return*this;
    }
    template<class T>
    T get()
    {
        //想要获取的数据类型，必须和保存的数据类型一致
        assert(typeid(T) == _content->type());
        return ((placeholder<T>*)_content)->_val;
    }
    template<class T>
    Any& operator=(const T&val)
    {
        Any(val).swap(*this);
        return *this;
    }
    Any&operator=(const Any&other)
    {
        Any(other).swap(*this);
        return *this;
    }
     // 获取数据类型：供外部检查类型
    // const std::type_info& type()
    // {
    //     return _content->type();
    // }
     const std::string type_name()
    {
        return _content->type().pretty_name();  // 调用pretty_name获取可读名称
    }
};

class Test
{
public:
    Test(){std::cout<<"构造"<<std::endl;}
    Test(const Test&other){std::cout<<"拷贝构造"<<std::endl;}
    ~Test(){std::cout<<"析构"<<std::endl;}
};
int main()
{
    std::any a;
    a=10;
    std::cout<<std::any_cast<int>(a)<<std::endl;
    a=std::string("hello");
    std::cout<<std::any_cast<std::string>(a)<<std::endl;

    std::any b;
    b=100;
    int*p=std::any_cast<int>(&b);
    std::cout<<*p<<std::endl;
    // Any a;

    // {
    //     Test t;
    //     a=t;
    // }


    // Any a(123);
    // Any b(std::string("sdada"));
    //  // 获取可读类型名
    // // std::cout<<a.type().name<<std::endl;
    //  std::cout<<a.type_name()<<std::endl;
    // std::cout<<a.get<int>()<<std::endl;
    // //  std::cout<<b.type().name()<<std::endl;
    //  std::cout<<b.type_name()<<std::endl;
    // std::cout<<b.get<std::string>()<<std::endl;
    // a=std::string("nihao");
    // std::cout<<a.get<int>()<<std::endl;
    return 0;
}